package com.twu.biblioteca;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.Scanner;

public class Menu {

    private Scanner scanner;
    private Collection collection;
    UserLog userLog;
    private TreeMap<Integer, Option> optionMap;
    public User loggedInUser;

    public Menu(Scanner scanner, Collection collection, UserLog userLog,
                Option[] options) {

        this.scanner = scanner;
        this.collection = collection;
        this.userLog = userLog;
        //optionMap = buildOptionMap();
        this.optionMap = buildOptionMap(options);
        this.loggedInUser = null;
    }

    public void run() {

        printWelcomeMessage();
        boolean quit = false;

        while (!quit) {

            printMenu();
            String optionInputString = scanner.nextLine();

            if (isQuitInput(optionInputString)) {
                quit = true;
                continue;
            }

            if (!isValidOption(optionInputString)) {
                printInvalidMessage();
                continue;
            }

            runOption(Integer.parseInt(optionInputString));
        }
    }

    private boolean isQuitInput(String input)  {
        return input.equals("q");
    }

    private TreeMap<Integer, Option> buildOptionMap() {

        TreeMap<Integer, Option> builtOptionMap = new TreeMap<Integer, Option>();

        builtOptionMap.put(new Integer(1), new OptionViewBooks(collection));
        builtOptionMap.put(new Integer(2), new OptionReserve(collection, scanner));
        builtOptionMap.put(new Integer(3), new OptionMembership());
        builtOptionMap.put(new Integer(4), new OptionViewMovies(collection));
        builtOptionMap.put(new Integer(5), new OptionLogIn(userLog, scanner));

        return builtOptionMap;
    }

    private TreeMap<Integer, Option> buildOptionMap(Option[] options) {

        TreeMap<Integer, Option> builtOptionMap = new TreeMap<Integer, Option>();

        for (int i = 0; i < options.length; i++) {
            builtOptionMap.put(new Integer(i + 1), options[i]);
        }

        return builtOptionMap;
    }

    private void runOption(Integer optionInput) {

        Option selectedOption = optionMap.get(optionInput);

        if (selectedOption instanceof OptionLogIn) {
            loggedInUser = (User) selectedOption.run(loggedInUser);
        }
        else {
            selectedOption.run(loggedInUser);
        }
    }

    private boolean isValidOption(String optionInput) {

        Integer optionInputInteger;

        try {
            optionInputInteger = new Integer(Integer.parseInt(optionInput));
        }
        catch (NumberFormatException e) {
            return false;
        }

        if (optionMap.keySet().contains(optionInputInteger)) {
            return true;
        }

        return false;
    }

    private void printWelcomeMessage()
    {
        System.out.println("Welcome!");
    }

    private void printInvalidMessage()
    {
        System.out.println("Select a valid option!!");
    }

    private void printMenu() {

        Iterator<Integer> optionKeyIterator = optionMap.keySet().iterator();

        while (optionKeyIterator.hasNext()) {
            Integer currentOptionKey = optionKeyIterator.next();
            System.out.println(currentOptionKey + ". "
                    + optionMap.get(currentOptionKey).menuDescription());
        }

        System.out.println("Type q to quit");
    }
}